<?php

namespace app\admin\controller\import;

use app\common\controller\Backend;
use think\Log;

/**
 * 导入辅助工具类
 * 提供数据导入过程中的各种工具方法
 */
class ImportHelper extends Backend
{
     /**
     * 布尔型字段映射关系
     * @var array
     */
    protected $booleanFields = [
        '是否预约' => ['是' => 1, '否' => 0],
        '是否派工' => ['是' => 1, '否' => 0],
        '是否代收' => ['是' => 1, '否' => 0],
        '是否第三方单' => ['是' => 1, '否' => 0],
        '是否拦截' => ['是' => 1, '否' => 0],
        '是否配送完结' => ['是' => 1, '否' => 0],
        '是否安装完结' => ['是' => 1, '否' => 0],
        '是否代收成功' => ['是' => 1, '否' => 0],
        '是否通电验机' => ['是' => 1, '否' => 0],
        '是否需要通电验机' => ['是' => 1, '否' => 0],
        '是否快递加送装' => ['是' => 1, '否' => 0],
        '是否送新拉旧' => ['是' => 1, '否' => 0],
        '是否收款成功' => ['是' => 1, '否' => 0],
        '是否需送装一体' => ['是' => 1, '否' => 0],
        '是否第三方' => ['是' => 1, '否' => 0],
        '是否逆向完结' => ['是' => 1, '否' => 0],
        '是否前置仓' => ['是' => 1, '否' => 0],
        '是否服务完结' => ['是' => 1, '否' => 0],
        '是否有增值服务费' => ['是' => 1, '否' => 0],
        '是否回访' => ['是' => 1, '否' => 0]
    ];
    
    // 在类顶部添加时间字段配置
protected $timeFields = [
    '用户原始期望配送时间',
    '终端应签收时间',
    '全程时效应签收时间',
    '网点预约时间',
    '上门取件完成时间',
    '支线应到达时间',
    '预计妥投时间',
    '实际妥投时间'
];

    /**
     * 处理行数据
     * @param array $rowData 原始行数据
     * @param array $fieldArr 字段定义
     * @return array
     */
    public function processRowData($rowData, $fieldArr)
    {
        $rows = [];
        $all = [];
        
        foreach ($rowData as $fieldName => $value) {
            $all[$fieldName] = $value;
            
            if (isset($fieldArr[$fieldName]) && $fieldName !== '') {
                $columnName = $fieldArr[$fieldName]['COLUMN_NAME'];
                $columnType = $fieldArr[$fieldName]['COLUMN_TYPE'];
                
                // 处理字段值
                $rows[$columnName] = $this->processFieldValue(
                    $value, 
                    $columnName, 
                    $columnType, 
                    $fieldArr[$fieldName]
                );
            }
        }
        
        return ['rows' => $rows, 'all' => $all];
    }

    /**
     * 处理字段值
     * @param mixed $value 原始值
     * @param string $columnName 列名
     * @param string $columnType 列类型
     * @param array $columnInfo 列信息
     * @return mixed
     */
    protected function processFieldValue($value, $columnName, $columnType, $columnInfo)
    {
        // 处理日期时间字段
        if (strpos($columnType, 'date') !== false || strpos($columnType, 'time') !== false) {
            return $this->formatDateTime($value, $columnName);
        }
        
        // 处理布尔型字段
        if (isset($this->booleanFields[$columnName])) {
            return $this->booleanFields[$columnName][trim($value)] ?? 0;
        }
        
        // 处理整数类型
        if (strpos($columnType, 'int') !== false && is_numeric($value)) {
            return (int)$value;
        }
        
        // 处理非空约束
        if ($value === '' && $columnInfo['IS_NULLABLE'] === 'NO') {
            return $this->getDefaultValue($columnInfo);
        }
        
        return $value;
    }

    /**
     * Excel数值日期转换为标准日期时间
     * @param float $excelDays Excel日期数值
     * @return string|null
     */
    public function excelToDateTime($excelDays)
    {
        try {
            if (!is_numeric($excelDays)) {
                return null;
            }
            
            $unixTimestamp = ($excelDays - 25569) * 86400;
            if ($excelDays >= 60) {
                $unixTimestamp -= 86400;
            }
            
            return date('Y-m-d H:i:s', $unixTimestamp);
        } catch (\Exception $e) {
            Log::error("Excel日期转换异常: ".$e->getMessage());
            return null;
        }
    }

    /**
     * 格式化日期时间值
     * @param mixed $value 输入值
     * @param string $fieldName 字段名
     * @return string|null
     */
    public function formatDateTime($value, $fieldName)
    {
        if (empty($value) || $value === 'NULL') {
            return null;
        }

        // 处理不完整的时间范围
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}-$/', $value)) {
            $datePart = rtrim($value, '-');
            if ($timestamp = strtotime($datePart)) {
                return date('Y-m-d H:i:s', $timestamp);
            }
        }

        // 处理完整时间范围
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}-\d{2}:\d{2}$/', $value)) {
            $datePart = explode('-', $value)[0];
            if ($timestamp = strtotime($datePart)) {
                return date('Y-m-d H:i:s', $timestamp);
            }
        }

        // 处理Excel数值日期
        if (is_numeric($value)) {
            try {
                if (class_exists('\PhpOffice\PhpSpreadsheet\Shared\Date')) {
                    $dateTime = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
                    return $dateTime->format('Y-m-d H:i:s');
                }
            } catch (\Exception $e) {
                Log::error("Excel时间转换失败[官方方法] - 字段: {$fieldName}, 值: {$value}");
            }
            
            $dateValue = $this->excelToDateTime($value);
            if ($dateValue) {
                return $dateValue;
            }
        }

        // 尝试各种日期格式
        $formats = ['Y-m-d H:i:s', 'Y/m/d H:i:s', 'Y年m月d日 H:i:s', 'Y-m-d H:i', 'Y/m/d H:i', 'Y-m-d', 'Y/m/d'];
        
        foreach ($formats as $format) {
            $date = \DateTime::createFromFormat($format, $value);
            if ($date !== false) {
                return $date->format('Y-m-d H:i:s');
            }
        }

        // 最后尝试strtotime
        if ($timestamp = strtotime($value)) {
            return date('Y-m-d H:i:s', $timestamp);
        }

        Log::error("无法识别的时间格式 - 字段: {$fieldName}, 值: {$value}");
        return null;
    }

    /**
     * 获取字段默认值
     * @param array $columnInfo 字段信息
     * @return mixed
     */
    public function getDefaultValue($columnInfo)
    {
        switch (true) {
            case strpos($columnInfo['COLUMN_TYPE'], 'int') !== false:
                return 0;
            case strpos($columnInfo['COLUMN_TYPE'], 'varchar') !== false:
            case strpos($columnInfo['COLUMN_TYPE'], 'text') !== false:
                return '';
            case strpos($columnInfo['COLUMN_TYPE'], 'decimal') !== false:
            case strpos($columnInfo['COLUMN_TYPE'], 'float') !== false:
                return 0.00;
            default:
                return null;
        }
    }
}